home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- ;----------------------------------------------------------
- ; FMULT -- version for use with assembly-language programs
- ;
- ; Copyright Bob Kline 1988
- ;
- ; Purpose:
- ; Multiply two single-precision floating-point numbers.
- ;
- ; Input:
- ; DX:AX contain multiplicand in single-precision IEEE
- ; format; CX:BX contain multiplier, same format.
- ;
- ; Output:
- ; Product (IEEE) single-precision real in DX:AX.
- ;
- ; Other registers used:
- ; Values changed in BP, SI, DI, BX, CX
- ;
- ; Procedures called:
- ; None.
- ;
- ; Comments:
- ; Sets variable _errno to ERANGE if overflow
- ; occurs. If a calling routine will be testing
- ; _errno, it must first reset the variable to
- ; zero to be sure that an error code is not
- ; left over from some previous call.
- ;----------------------------------------------------------
-
- .MODEL SMALL
-
- PUBLIC FMULT
- EXTRN _errno:WORD
-
- EXPONENT EQU BP
- ERANGE EQU 34
-
- .CODE
-
- FMULT PROC
-
- ; get sign of result and save it
- MOV SI,DX
- XOR DX,CX
- AND DX,8000h
- PUSH DX
- MOV DX,SI
-
- ; add exponents, save result
- MOV EXPONENT,CX
- MOV DI,DX
- SHL DX,1
- SHL CX,1
- XCHG DH,DL
- XCHG CH,CL
- XOR DH,DH
- XOR CH,CH
- SUB CX,127
- SUB DX,127
- ADD CX,DX
- XCHG EXPONENT,CX
- MOV DX,DI
-
- ; unpack mantissas
- AND DX,7Fh
- AND CX,7Fh
- OR DX,80h
- OR CX,80h
-
- ; multiply DX:AX by CX:BX; since only 24 bits each in multiplier
- ; and multiplicand, result will have 47 or 48 bits, so we would
- ; only need 3 registers for the result -- but we actually only
- ; need 2 since final mantissa can only use the most significant
- ; 24 bits. We will look at the 25th bit for rounding decision
- ; before throwing it away
- PUSH DX
- PUSH DX
- PUSH AX
- MUL BX ; A x B
- MOV SI,DX
- POP AX
- MUL CX ; A x C
- ADD SI,AX
- MOV DI,DX
- ADC DI,0
- POP AX
- MUL BX ; D x B
- ADD SI,AX
- ADC DI,DX
- POP AX
- MUL CX ; D x C
- ADD DI,AX
- MOV AX,SI
- MOV DX,DI
-
- ; if result is 47 bits, shift it up into the 48th bit
- JS L0
- SHL AX,1
- RCL DX,1
- JMP SHORT L1
- L0: INC EXPONENT
-
- ; quick 8-bit left shift
- L1: XCHG AH,AL
- XCHG DL,AH
- XCHG DH,DL
-
- ; round up if necessary
- TEST DH,80h
- JZ L2
- AND DX,0FFh
- INC AX
- JNC L2
- INC DX
-
- ; and adjust exponent if we rounded all the way through the top bit
- TEST DH,1
- JZ L2
- INC EXPONENT
-
- ; make the top bit invisible
- L2: AND DX,7Fh
-
- ; get the exponent back
- MOV BX,EXPONENT
- ADD BX,127
-
- ; check to make sure the exponent isn't out of range
- OR BH,BH
- JZ L3
- MOV _errno,ERANGE
- XOR BH,BH
-
- ; get back into position for packing and fold it in
- L3: XCHG BH,BL
- SHR BX,1
- OR DX,BX
-
- ; get the sign back and return
- POP CX
- OR DX,CX
- RET
-
- FMULT ENDP
-
- END